← Back to portfolio case-study · David Silverlight
◆ Angular · NgRx · Data Query UX

API Builder

Liquidware's Stratusphere UX captures millions of rows of digital-workspace telemetry. Its REST API could surface any of it, if you already knew the schema. I built the interface that made that power point-and-click.

8 InspectorsBasis lookupsColumn & filter refinementLive JSON + URLSaved queriesCSV / JSON export
1.2M+Rows queryable
ZeroSchema knowledge needed
2020–22Lead Angular dev
1,204,873 ROWS API BUILDER inspector · basis · columns 12 ROWS RETURNED ux_score · latency login_delay SIGNAL
01 / The brief

A powerful API that almost nobody could use

Stratusphere UX monitors digital workspaces and VDI estates, collecting a relentless stream of performance telemetry: UX scores, login delay, app load time, CPU queue, pagefile pressure, disk IOPS, session latency, and dozens more metrics, captured per user, per machine, per application, per hour.

All of it was already reachable through a REST API that returned JSON or CSV. The catch was the cost of entry. To ask a question, a customer had to know which inspector id mapped to the data they wanted, which basis key to pivot on, and the exact column names buried in the underlying schema. In practice that meant reading documentation, hand-assembling a JSON payload, and hoping the URL came back with something useful.

The result was a capability that shipped with the product but rarely left the hands of the people who had built it. The brief was to close that gap: let any customer interrogate their own data confidently, without teaching them the database.

02 / My role

Lead Angular Developer

I owned the front end end to end, from the query model and state architecture through to the shipped UI:

  • Designed the Inspector-first query model
  • Architected the NgRx store and the three-layer HTTP stack
  • Built the composer, results grid, and charting
  • Delivered theming, i18n, export, history and favorites
◆ Liquidware Labs · 2020–2022
03 / The shift

From "read the schema" to "point and click"

The same query, asked two ways. The builder did not add capability to the API, it removed the prerequisites for using it.

Before · hand-assembled
GET /lwl/api?json={
  "inspector": "0",          ← which id?
  "basis": "machine_groups", ← which key?
  "columns": "ux_score,
              cpu_queue,
              memory_used",   ← exact names?
  "date": "2 hours",
  "limit": "0"
}

# Prerequisites:
#   schema documentation
#   inspector id reference
#   valid column spellings
#   trial and error

The friction. Every question started with research. A typo in a column name returned nothing, with no hint as to why.

BUILDER →
After · composed visually
// 1. Pick an Inspector  (what kind of data)
   ▸ Summary   ▸ Applications   ▸ Remote Display
   ▸ Network   ▸ Extension      ▸ Alerts

// 2. Choose a lookup basis  (how to pivot)
   ☑ Machine Groups     ☐ Users (ID)
   ☐ Machines           ☐ User Name

// 3. Refine columns, filters, sorting, date
   ☑ ux_score  ☑ cpu_queue  ☑ memory_used

// 4. Builder emits the payload, live:
{ "inspector":"0", "basis":"machine_groups",
  "columns":"ux_score,cpu_queue,memory_used",
  "date":"2 hours", "limit":"0" }

   [ Launch ]  [ Copy ]  [ Save as favorite ]

The shift. The schema became a set of labelled choices. Results render immediately, and the generated JSON and URL stay visible so power users can still take them elsewhere.

04 / The query model

Three decisions, in the order a person actually thinks

Rather than mirroring the API's parameter list, the builder walks the user down a funnel: what kind of data, how to pivot it, then how to sharpen it.

🔍

Inspect

An Inspector scopes the question to a domain: users, machines, applications, remote display, network, extensions or alerts. One choice eliminates most of the schema before the user sees it.

🧮

Pivot

A lookup basis decides the grain of the answer. Multiple bases can be combined to increase detail, with searchable basis names in list or grid view for large estates.

🎯

Refine

Dedicated tabs for columns, filters, sorting, output and date turn the broad set into a precise one, with related metric groups selectable together instead of column by column.

05 / Architecture

A three-layer HTTP stack, and one source of truth

Inspector metadata is large, slow to fetch and rarely changes. Query state is small, volatile and shared across seven tabs. Those two facts drove the whole design.

BuilderServiceLayer 3 · endpoints

CRUD operations for saved queries, favorites and history. The only layer that knows about builder-specific endpoints, so query persistence evolved without touching transport code.

ApiServiceLayer 2 · business logic

Query composition and validation, publishing changes over RxJS Subjects. Components subscribe to what they care about instead of calling each other, which kept coupling low across the tabbed composer.

DataServiceLayer 1 · transport

Raw HTTP with retry logic and localStorage caching. Caching inspector metadata locally made the composer feel instant on return visits and offline-tolerant when the hub was slow.

Alongside it, a centralized NgRx store split into three slices, with 20+ reducer handlers and async effects for session verification, inspector metadata and basis-name fetching.

builderThe query under construction: inspector, basis, columns, filters, sorting, date.
usersSession verification and profile state, resolved through effects on load.
spotChecksSaved spot-check definitions, isolated from the live composer state.

On top of that foundation: dynamic theming via DOM stylesheet replacement with PrimeNG ::ng-deep overrides, an i18n pipeline backed by JSON locale files with runtime locale switching, and favorite queries made shareable through URL-encoded query parameters.

06 / The interface

Composer, payload and result in one view

The builder never hides its work. As choices are made, the JSON and URL update in place and the grid below re-renders. Click any screen to enlarge.

Stratusphere API Builder main screen: inspectors, summary inspector lookup basis, saved queries panel and live results grid
The composerInspectors and lookup basis on the left, saved queries on the right, and the full telemetry grid streaming results underneath.
Stratusphere API Builder showing generated API JSON and a launchable API URL
Live payloadThe generated JSON and launchable URL, with New, Simple and Extended views plus one-click copy and encode.
Stratusphere API Builder inspector grid view with searchable basis names and checkbox selection
Grid viewInspectors laid out as cards with their basis names inline, for scanning the schema rather than searching it.
Stratusphere API Builder inspector list view with basis name search
List viewThe same metadata as a dense searchable list, filtered live by basis or column name.
Stratusphere API Builder saved queries panel with editable favorites
Saved queriesNamed, described and editable favorites, so a hard-won query becomes a reusable asset.
Stratusphere API Builder favorites shortcuts docked in the left navigation
ShortcutsFavorites promoted into the left rail, turning routine investigations into a single click.
Stratusphere API Builder light theme with UX Score chart and refined per-user results grid
Charted resultUX Score visualized per user with the refined grid beneath, in the light theme.
07 / Outcome

A shipped feature customers could actually reach

API Builder ships inside Stratusphere and is reachable from any hub. Version 2 extended the model with related metric column groups, importable and saveable API calls, and a full history of previous queries.

0Lines of schema documentation a user must read
7Composer tabs: main, search, columns, filters, sorting, output, date
20+NgRx reducer handlers behind one source of truth
2Export formats, plus clipboard and shareable URLs

The interesting design problem here was not the visuals, it was deciding what to hide. Stratusphere's schema is genuinely large, and the temptation is to expose all of it behind search. Leading with the Inspector meant the first click eliminated most of the schema, so every subsequent choice stayed small enough to make confidently.

08 / Under the hood

Angular 9, NgRx, and a lot of RxJS

A modular single-page application with lazy components and scroll-position restoration, built to stay responsive while rendering very wide result grids.

Angular 9NgRx 9RxJS 6TypeScript 3.8PrimeNG Chart.jsAmCharts 4XLSXJasmine / Karma localStorage / CookiesRESTi18n
×enlarged screenshot